package miage.rest.resource.candidature;

import com.thoughtworks.xstream.XStream;
import miage.rest.db.Database;
import miage.rest.routing.UriTemplateFinder;
import org.restlet.resource.ResourceException;
import org.restlet.resource.ServerResource;
import java.io.IOException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import miage.rest.model.Statut;
import miage.rest.xml.XstreamRepresentation;
import miage.rest.form.Form;
import miage.rest.model.Candidature;
import org.restlet.data.Status;
import org.restlet.representation.Representation;
import org.restlet.resource.Get;
import org.restlet.resource.Put;
import miage.rest.resource.ResourceError;
import miage.rest.security.Roles;
import miage.rest.validation.IntegerRangeValidator;
import miage.rest.validation.IntegerValidator;
import miage.rest.validation.LongRangeValidator;
import miage.rest.xml.xstream.converter.HrefConverter;

/**
 *
 * @author Lou
 */
public class StatutResource extends ServerResource {

	private final Database database;
	private UriTemplateFinder uriTemplateFinder;
	private Candidature candidature;

	public StatutResource(Database database, UriTemplateFinder uriTemplateFinder) {
		super();
		this.database = database;
		this.uriTemplateFinder = uriTemplateFinder;
	}

	/** Initialisation de la ressource a partir de la chaine d'url */
	@Override
	protected void doInit() throws ResourceException {
		Long idCandidature;
		final String sqlCandidature = "SELECT id_candidature FROM candidature WHERE id_candidature = ?";

		String idCandidatureAttribute = getRequest().getAttributes().get(
				"idCandidature").toString();

		//Validation de l'id de la candidature
		LongRangeValidator longRangeValidator = new LongRangeValidator(1l, null);

		//Validation de l'id de la session
		if (longRangeValidator.isValid(idCandidatureAttribute)) {
			idCandidature = Long.parseLong(idCandidatureAttribute);
		} else {
			getResponse().setEntity(ResourceError.getNewRepresentation("invalidCandidatureId"));
			throw new ResourceException(Status.CLIENT_ERROR_BAD_REQUEST);
		}

		//Recuperation de la candidature
		try {
			candidature = database.fetchRow(sqlCandidature, Candidature.class,idCandidature);

			if (candidature == null) {
				setExisting(false);
			}
		} catch (SQLException e) {
			throw new ResourceException(Status.SERVER_ERROR_INTERNAL, e);
		}
	}

	@Get
	public Representation doGet() throws Exception {
		Representation response = null;
		String sqlStatut = "SELECT candidature.id_statut, nomstatut "
							+ "FROM candidature, statut "
							+ "WHERE candidature.id_candidature = " + candidature.getIdCandidature() + " "
							+ "AND candidature.id_statut = statut.id_statut";

		Statut statut = database.fetchRow(sqlStatut, Statut.class);

		if (statut == null) {
			setStatus(Status.SERVER_ERROR_INTERNAL);
			response = ResourceError.getNewRepresentation("statut de la candidature non trouvée");
		} else {
			response = new XstreamRepresentation<Statut>(statut);
		}
		
		return response;
	}

	/**
	 * Reponse a une requete PUT
	 * Modification du statut d'une candidature
	 * @param entity
	 * @return
	 * @throws IOException
	 */
	@Put
	public Representation doPut(Representation entity) throws Exception {

		if (!isInRole(Roles.ADMIN.getName())) {
			throw new ResourceException(Status.CLIENT_ERROR_UNAUTHORIZED);
		}

		List<ResourceError> errors = new ArrayList<ResourceError>();
		Representation response = null;

		Form form = new Form(entity);
		form.addValidator("statut", new IntegerRangeValidator(0, 100));

		if (!form.isValid()) {
			setStatus(Status.CLIENT_ERROR_BAD_REQUEST);
			for (String msg : form.getMessages()) {
				errors.add(new ResourceError(msg));
			}
		} else {
			String sqlUpdateCandidature = "UPDATE candidature SET id_statut = ? WHERE id_candidature = ?";

			database.update(sqlUpdateCandidature, Integer.parseInt(form.getFirstValue("statut")), candidature.getIdCandidature());

			response = new XstreamRepresentation<Candidature>(candidature);
			
			XStream xstream = ((XstreamRepresentation) response).getXstream();
			xstream.registerConverter(new HrefConverter(
					Candidature.class,
					xstream.getConverterLookup(),
					uriTemplateFinder.find(CandidatureResource.class)));
			setStatus(Status.SUCCESS_NO_CONTENT);
		}

		if (!errors.isEmpty()) {
			response = ResourceError.getNewRepresentation(errors);
		}
		
		return response;
	}
}
